#include "main.h"
#include <string.h>
static uint8_t sendBuffer[50];
/* 霍尔传感器计数 */
volatile uint32_t Hall_Count = 0;
/*模式变量*/
uint8_t mode = 1;//1自动2手动3淋浴
/*设置变量*/
int temx = 26;
int humx = 50;
int wattx = 30;
int watsx = 800;

/* 各个任务句柄 */
TasksHandle_t  *Tasks_Handle;
/* 互斥锁。。。 */
SemaphoreHandle_t Mutex;
/* 事件组句柄 */
EventGroupHandle_t Event_Group_Handle;
/* 任务函数声明 */
static void UserLed_Task(void *pvParameters);
static void ScreenData_Parse_Task(void *pvParameters);
static void DHT11_Data_Read_Task(void *pvParameters);
static void VL53L0x_Data_Read_Task(void *pvParameters);
static void DS18B20_Data_Read_Task(void *pvParameters);
static void TDS_Data_Read_Task(void *pvParameters);
/* 创建任务 APP */
void Create_APP_Task(void)
{   
    taskENTER_CRITICAL();//进入临界区
    Tasks_Handle = (TasksHandle_t *)pvPortMalloc(sizeof(TasksHandle_t));//分配内存
    /* 互斥锁初始化 */
    Mutex = xSemaphoreCreateMutex();
    /* 创建事件组 */
    Event_Group_Handle = xEventGroupCreate();
    /* 创建任务 */
    xTaskCreate((TaskFunction_t )UserLed_Task, //任务函数
                (const char*    )"UserLed_Task", //任务名称
                (uint16_t       )128, //任务堆栈大小
                (void*          )NULL, //传递给任务函数的参数
                (UBaseType_t    )osPriorityNormal, //任务优先级
                (TaskHandle_t*  )&Tasks_Handle->UserLed_Task_Handle); //任务句柄
    xTaskCreate((TaskFunction_t )ScreenData_Parse_Task, //任务函数
                (const char*    )"ScreenData_Parse_Task", //任务名称
                (uint16_t       )256, //任务堆栈大小
                (void*          )NULL, //传递给任务函数的参数
                (UBaseType_t    )osPriorityNormal + 1, //任务优先级
                (TaskHandle_t*  )&Tasks_Handle->ScreenData_Parse_Task_Handle); //任务句柄
    xTaskCreate((TaskFunction_t )DHT11_Data_Read_Task, //任务函数
                (const char*    )"DHT11_Data_Read_Task", //任务名称
                (uint16_t       )128, //任务堆栈大小
                (void*          )NULL, //传递给任务函数的参数
                (UBaseType_t    )osPriorityNormal , //任务优先级
                (TaskHandle_t*  )&Tasks_Handle->DHT11_Data_Read_Task_Handle); //任务句柄
    xTaskCreate((TaskFunction_t )VL53L0x_Data_Read_Task, //任务函数
                (const char*    )"VL53L0x_Data_Read_Task", //任务名称
                (uint16_t       )128, //任务堆栈大小
                (void*          )NULL, //传递给任务函数的参数
                (UBaseType_t    )osPriorityNormal, //任务优先级
                (TaskHandle_t*  )&Tasks_Handle->VL53L0x_Data_Read_Task_Handle); //任务句柄
    xTaskCreate((TaskFunction_t )DS18B20_Data_Read_Task, //任务函数
                (const char*    )"DS18B20_Data_Read_Task", //任务名称
                (uint16_t       )128, //任务堆栈大小
                (void*          )NULL, //传递给任务函数的参数
                (UBaseType_t    )osPriorityNormal, //任务优先级
                (TaskHandle_t*  )&Tasks_Handle->DS18B20_Data_Read_Task_Handle); //任务句柄
		xTaskCreate((TaskFunction_t )TDS_Data_Read_Task, //任务函数
                (const char*    )"TDS_Data_Read_Task", //任务名称
                (uint16_t       )128, //任务堆栈大小
                (void*          )NULL, //传递给任务函数的参数
                (UBaseType_t    )osPriorityNormal, //任务优先级
                (TaskHandle_t*  )&Tasks_Handle->TDS_Data_Read_Task_Handle); //任务句柄
    taskEXIT_CRITICAL();//退出临界区
}

/* User LED Task */
static void UserLed_Task(void *pvParameters)
{
    while (1)
    {
        /* 任务代码 */
        USER_LED_TOGGLE();//LED灯闪烁
        vTaskDelay(1000);//延时1s
    }
}
/* 等待处理串口屏数据任务 */
static void ScreenData_Parse_Task(void *pvParameters)
{   
    EventBits_t BitsRetuen;
    while (1)
    {
        BitsRetuen = xEventGroupWaitBits(Event_Group_Handle, SCREEN_DATA_RECIV_BIT, pdTRUE, pdFALSE, portMAX_DELAY); //等待事件
        if (BitsRetuen & SCREEN_DATA_RECIV_BIT) //判断是否接收到屏幕数据
        {
            //解析处理屏幕数据
					DebugUart_SendData(ScreenUart_RxBuffer);
					//判断是否为模式切换
					if(ScreenUart_RxBuffer[0]==0x01)
					{
						mode = 1;//自动模式
					}
					else if(ScreenUart_RxBuffer[0]==0x02)
					{
						mode = 2;//手动模式
						Set_Fan_State(FAN_STATE_OFF);//默认关闭风扇
						HAL_GPIO_WritePin(HOTLED_GPIO_PORT,HOTLED_GPIO_PIN,0);//默认关闭加热灯
					}
					else if(ScreenUart_RxBuffer[0]==0x03)
					{
						mode = 3;//淋浴模式
						Set_Fan_State(FAN_STATE_OFF);//关闭风扇
						HAL_GPIO_WritePin(HOTLED_GPIO_PORT,HOTLED_GPIO_PIN,0);//关闭加热灯
					}
					else if(ScreenUart_RxBuffer[0]==0x04)
					{
						HAL_GPIO_WritePin(HOTLED_GPIO_PORT,HOTLED_GPIO_PIN,1);//打开加热灯
					}
					else if(ScreenUart_RxBuffer[0]==0x05)
					{
						HAL_GPIO_WritePin(HOTLED_GPIO_PORT,HOTLED_GPIO_PIN,0);//关闭加热灯
					}
					else if(ScreenUart_RxBuffer[0]==0x06)
					{
						Set_Fan_State(FAN_STATE_ON);//打开风扇
					}
					else if(ScreenUart_RxBuffer[0]==0x07)
					{
						Set_Fan_State(FAN_STATE_OFF);//关闭风扇
					}
					else if(ScreenUart_RxBuffer[0]==0x11)//温度
					{
						temx--;
					}
					else if(ScreenUart_RxBuffer[0]==0x12)
					{
						temx++;
					}
					else if(ScreenUart_RxBuffer[0]==0x21)//湿度
					{
						humx--;
					}
					else if(ScreenUart_RxBuffer[0]==0x22)
					{
						humx++;
					}
					else if(ScreenUart_RxBuffer[0]==0x31)//水温
					{
						wattx--;
					}
					else if(ScreenUart_RxBuffer[0]==0x32)
					{
						wattx++;
					}
					else if(ScreenUart_RxBuffer[0]==0x41)//水位
					{
						watsx--;
					}else if(ScreenUart_RxBuffer[0]==0x42)
					{
						watsx++;
					}

					//HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,0);
          memset(ScreenUart_RxBuffer, 0, sizeof(ScreenUart_RxBuffer)); // 清空接收缓冲区
          //...
        }
    }
}
/* DHT11 数据读取任务 */
static void DHT11_Data_Read_Task(void *pvParameters)
{   
    uint8_t temp, humi;
    while(1)
    {   
        HAL_Delay(1000);
        xSemaphoreTake(Mutex, portMAX_DELAY); //获取互斥锁
        DHT11_Read_Data(&temp, &humi); //读取DHT11数据
        sprintf((char *)sendBuffer, "tem.val=%d\xff\xff\xff", temp); //格式化温度数据
        DebugUart_SendData(sendBuffer); //发送数据到Debug串口
				ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
				memset(sendBuffer,0,sizeof(sendBuffer));//清空
			
				sprintf((char *)sendBuffer, "hum.val=%d\xff\xff\xff", humi); //格式化湿度数据
        DebugUart_SendData(sendBuffer); //发送数据到Debug串口
				ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
				memset(sendBuffer,0,sizeof(sendBuffer));//清空
			
				if(mode==1)//自动模式
				{
					if(temp>=temx||humi>=humx)
					{
							Set_Fan_State(FAN_STATE_ON);//开启排气扇
					}
					else
					{
							Set_Fan_State(FAN_STATE_OFF);//关闭排气扇
					}
				}

        xSemaphoreGive(Mutex); //释放互斥锁
        vTaskDelay(1000); //延时1s
    }
}
/* VL53L0x 读取任务 */
static void VL53L0x_Data_Read_Task(void *pvParameters)
{   
    extern uint16_t VL53L0X_GetValue(void);
    uint16_t distance;
    while(1)
    {   
        xSemaphoreTake(Mutex, portMAX_DELAY); //获取互斥锁
        distance = VL53L0X_GetValue();
				distance = 1000-distance;//假设水热水器水箱高1000mm
        sprintf((char *)sendBuffer, "wats.val=%d\xff\xff\xff", distance); //格式化数据
        DebugUart_SendData(sendBuffer); //发送数据到串口
				ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
				memset(sendBuffer,0,sizeof(sendBuffer));//清空
				if(mode == 1)//自动模式
				{
					if(distance < watsx)
					{
						HAL_GPIO_WritePin(WATLED_GPIO_PORT,WATLED_GPIO_PIN,1);
					}
					else
					{
						HAL_GPIO_WritePin(WATLED_GPIO_PORT,WATLED_GPIO_PIN,0);
					}
				}
        xSemaphoreGive(Mutex); //释放互斥锁
        vTaskDelay(1000); //延时1s
    }
}
/* DS18B20 读取任务 */
static void DS18B20_Data_Read_Task(void *pvParameters)
{   
    float temp = 0;
		uint8_t num = 0;
    while(1)
    {
        xSemaphoreTake(Mutex, portMAX_DELAY); //获取互斥锁
        DS18B20_ConvertT(); //读取DS18B20温度
        vTaskDelay(10); //延时1s
        temp = DS18B20_ReadT(); //读取DS18B20温度
				num = temp/1;
        sprintf((char *)sendBuffer, "watt.val=%d\xff\xff\xff", num); //格式化数据
        DebugUart_SendData(sendBuffer); //发送数据到串口
				ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
				memset(sendBuffer,0,sizeof(sendBuffer));//清空
				if(mode==1)//自动模式
				{
					if(num < wattx )
					{
							HAL_GPIO_WritePin(WATHOT_GPIO_PORT,WATHOT_GPIO_PIN,1);//打开水加热
					}
					else
					{
							HAL_GPIO_WritePin(WATHOT_GPIO_PORT,WATHOT_GPIO_PIN,0);//关闭水加热
					}
				}			
        xSemaphoreGive(Mutex); //释放互斥锁
        vTaskDelay(1000); //延时1s
    }
}
/* TDS 读取任务 */
static void TDS_Data_Read_Task(void *pvParameters)
{   
    float ppm = 0;
		uint8_t  num = 0;
    while(1)
    {
        xSemaphoreTake(Mutex, portMAX_DELAY); //获取互斥锁
				ppm = TDS_GetData_PPM();  
				num = ppm*100;
        sprintf((char *)sendBuffer, "ppm.val=%d\xff\xff\xff", num); //格式化水质数据
        DebugUart_SendData(sendBuffer); //发送数据到串口
				ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
				memset(sendBuffer,0,sizeof(sendBuffer));//清空
			
				if(num >200)
					{		
						//发送异常信息
						sprintf((char *)sendBuffer, "errline1.txt=\"Warning: Abnormal water quality\"\xff\xff\xff");
						ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
						memset(sendBuffer,0,sizeof(sendBuffer));//清空
						sprintf((char *)sendBuffer, "errline2.txt=\"Warning: Abnormal water quality\"\xff\xff\xff");
						ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
						memset(sendBuffer,0,sizeof(sendBuffer));//清空
						sprintf((char *)sendBuffer, "errline3.txt=\"Warning: Abnormal water quality\"\xff\xff\xff");
						ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
						memset(sendBuffer,0,sizeof(sendBuffer));//清空
						//蜂鸣器警报提示
						int i = 0;
						for(i = 0;i < 3;i++)
							{
								HAL_GPIO_WritePin(BUZZER_GPIO_PORT,BUZZER_GPIO_PIN,0);
								vTaskDelay(1000);
								HAL_GPIO_WritePin(BUZZER_GPIO_PORT,BUZZER_GPIO_PIN,1);
							}
					}
					else
					{
						//发送无异常信息
						sprintf((char *)sendBuffer, "errline1.txt=\"No abnormality\"\xff\xff\xff");
						ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
						memset(sendBuffer,0,sizeof(sendBuffer));//清空
						sprintf((char *)sendBuffer, "errline2.txt=\"No abnormality\"\xff\xff\xff");
						ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
						memset(sendBuffer,0,sizeof(sendBuffer));//清空
						sprintf((char *)sendBuffer, "errline3.txt=\"No abnormality\"\xff\xff\xff");
						ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
						memset(sendBuffer,0,sizeof(sendBuffer));//清空
					}
				sprintf((char *)sendBuffer, "wato.val=%d\xff\xff\xff", Hall_Count); //格式化水流量数据
			  DebugUart_SendData(sendBuffer); //发送数据到串口
				ScreenUart_SendData(sendBuffer);//发送数据到LCD串口
				memset(sendBuffer,0,sizeof(sendBuffer));//清空
        xSemaphoreGive(Mutex); //释放互斥锁
        vTaskDelay(1000); //延时1s
    }
}